
/* ###############################################

		1. Written date 		>> 	2007. 1. 29
		2. File Name 		>> 	ClientMGR.h
 		3. Contents 		>>	서버의 소켓 관리 매니저 클래스...
 		4. Written by 		>>	최철호	
 		5. Last Revision Date	>>	2007. 1. 29
										
################################################ */

#include "ClientMGR.h"

// ####################################################################

// Server >> Client Message
#define SEND_FILE_BY_MACADDRESS		10000001
#define NOT_FOUND_MACADDRESS		10000002
#define NOT_FOUND_BOOKMARK			10000003
#define SEND_FILE_BY_URL			10000004
#define NOT_FOUND_URL				10000005
#define SEND_FILE_BY_TAG			10000006
#define NOT_FOUND_TAG				10000007

// Client >> Server Message
#define CHECK_MACADDRESS			20000001		
#define CHECK_URL					20000002
#define CHECK_TAG					20000003

// ####################################################################

int CompareByClient( void* one, void* other )
{
	int ret = -1;
	
	if( *((Client*)one) == *((Client*)other) )
	{
		ret = 0;
	}
	
	return ret;
}


//////////////////////////////////////////////////////////////////////////////////////////
// Constructor & Destructor																//
//////////////////////////////////////////////////////////////////////////////////////////

//Constructor
ClientMGR::ClientMGR( int lines ): clients( lines )
{
	this->lines = 0;
}

//Desturctor
ClientMGR::~ClientMGR()
{

}

//Copy Constructor
ClientMGR::ClientMGR( const ClientMGR& source ): clients( source.clients )
{
	this->lines = source.lines;
}


//////////////////////////////////////////////////////////////////////////
// Operators															//
//////////////////////////////////////////////////////////////////////////

// = Operator
ClientMGR& ClientMGR::operator = ( const ClientMGR& source )
{
	this->lines = source.lines;
	this->clients = source.clients;

	return (*this);
}


// [] Operator
Client& ClientMGR::operator [] (int index)
{
	    return  this->clients[ index ];
}

Client* ClientMGR::operator + (int index)
{
	    return  this->clients + index;
}

//////////////////////////////////////////////////////////////////////////
// Member Functions														//
//////////////////////////////////////////////////////////////////////////

int ClientMGR::Record( string ipAddress, PSocket* clientSocket )
{
	int index = this->clients.Store( this->lines, Client( ipAddress, clientSocket ) );

	if( index >= 0 )
	{
		(this->lines++);
	}

	return index;
}

Client* ClientMGR::Record( PSocket* clientSocket, string ipAddress )
{
	Client* ret = 0;

	int index = this->clients.Store( this->lines, Client( ipAddress, clientSocket ) );

	if( index >= 0 )
	{
		ret = this->clients + index;
		(this->lines++);
	}

	return ret;
}

int ClientMGR::FindClient( Client* client )
{
	int index = -1;
	
	if( this->lines !=0 )
	{
		index = this->clients.LinearSearchUnique( client, CompareByClient );
	}
	
	return index;
}
void ClientMGR::DisConnectClient( int index )
{
	for( int i=0 ; i<this->lines-1 ; i++ )
	{
		if( this->clients[index] == this->clients[i] )
		{
			for( ; i<this->lines-1 ; i++ )
			{
				this->clients[i] = this->clients[i+1];
			}
			break;
		}
	}

	printf( "Log Out [%d]\n", this->lines ); 
	
	this->lines--;
}

// 맥어드래스를 전송받아서 해당 북마크를 찾고, 찾은 북마크가 가진 태그 별로 RSS 문서를 만들어 장치에 전송한다.
void ClientMGR::OnCheckMacAddress( Client* client, TransferMessage transferMessage )
{/*
	int transferCount;

	string macAddress;

	// Get PUB MacAddress
	macAddress = transferMessage.contents;
	printf( ">>[ recv MAC : %s ]\n", macAddress.c_str() );

	#if 0 // 실제코드...
	// Find UserInformation by PUB MacAddress
	UserInformation* userInformation = this->GetUserMGR().Find( macAddress );

	// Get User BookMarkList...
	BookMarkList bookMarkList = userInformation->GetBookMarkList();
		
	transferCount = bookMarkList.GetCountOfbookMarks();			 	
 	#endif 
	 	
 	#if 1 // 5 files 임시코드...
 	transferCount = 5;
	 #endif 	
	 	
	// 파일전송 메세지 생성 및 전송
	transferMessage.type = SEND_FILE_BY_MACADDRESS;
	strcpy( transferMessage.contents, "" );
	client->GetClientConnectSocket()->Write( &transferMessage, sizeof(TransferMessage) );

	#if 0 // 실제코드... 리스트 파일을 생성하여 파일 목록을 생성한다...	
	FILE* rssList = fopen( "RSSLIST.dat", "wt" );
				
	string fileName;
				
	
	for( int j=0 ; j<transferCount ; j++ )
	{					
		Tag* tag = bookMarkList[j].GetTag();

		thisGetItemMGR().Find( tag, &itemCount, &itemSet );

		fileName = this->XmlGenerator( tag->GetTitle(), itemCount, itemSet );
			
		fprintf( rssList, "%s\n", fileName.c_str() );				
	}
	
	fclose( rssList );
	
	#endif
		
	// 파일 압축...		
	macAddress += "._RSS.tar.gz";
				
	string mvfile = "mv rss.tar.gz ";
	
	mvfile += macAddress;		// "mv rss.tar.gz macAddress_RSS.tar.gz"
	
	system( "tar cvf rss.tar *.xml RSSLIST.dat" );
	system( "gzip rss.tar" );
	system( "chmod 777 rss.tar.gz");
	system( mvfile.c_str() );	
			
	// 파일 오픈..
	int len = 0;
	int fd = open( macAddress.c_str(), O_RDONLY );

	if( fd == -1 )
	{
		perror( "File Open Error" );
	}
	
	// 파일 전송
	while( ( len = read( fd, transferMessage.contents, sizeof(transferMessage.contents) ) ) != 0 )
	{
		// printf("%s", transferMessage.contents);
		client->GetClientConnectSocket()->Write( &transferMessage, len+4 );
		printf("TRANSFER FILE\n");	
	}

	// 삭제 명령 생성...
	string rmMsg = "rm -f ";
	
	rmMsg += macAddress;
	
	system( rmMsg.c_str() );

	printf( "1 FILE OK\n");
	
	close( fd );
	
	client->GetClientConnectSocket()->Close();
	*/
}

// URL 전송받아서 해당 URL의 html전송...
void ClientMGR::OnCheckURL(  Client* client, TransferMessage transferMessage  )
{/*
	string url = transferMessage.contents;	
	
	int len = 0;
			
	// 파일 전송 메세지 생성 및 전송
	transferMessage.type = SEND_FILE_BY_URL;
	strcpy( transferMessage.contents, "" );
	client->GetClientConnectSocket()->Write( &transferMessage, sizeof(TransferMessage) );

	char htmlName[256];
	printf( "%s.html", url.c_str() );
	sprintf( htmlName, "%s.html", url.c_str() );

	#if 0 // 실제코드.. 요청한 URL.html명의 파일 전송...	
	int fd = open( htmlName, O_RDONLY );
	#endif 
	
	#if 1 // 임시코드...트롤텍 메인 화면...
	int fd = open( "trollMain.html", O_RDONLY );
	#endif

	if( fd == -1 )
	{
		perror( "File Open Error" );
	}

	// 파일전송...
	while( ( len = read( fd, transferMessage.contents, sizeof(transferMessage.contents) ) ) != 0 )
	{
			client->GetClientConnectSocket()->Write( &transferMessage, len+4 );
	}
	
	close( fd );	
	
	client->GetClientConnectSocket()->Close();
	*/
}

// TAG 전송받아서 해당 TAG의 html전송...
void ClientMGR::OnCheckTAG( Client* client, TransferMessage transferMessage )
{/*
	string tag = transferMessage.contents;	
	
	int len = 0;

	// 파일 전송 메세지 생성 및 전송
	transferMessage.type = SEND_FILE_BY_TAG;
	strcpy( transferMessage.contents, "" );
	client->GetClientConnectSocket()->Write( &transferMessage, sizeof(TransferMessage) );

	char htmlName[256];
	printf( "%s.html", tag.c_str() );
	sprintf( htmlName, "%s.html", url.c_str() );

	#if 0 // 실제코드.. 요청한 URL.html명의 파일 전송...	
	int fd = open( htmlName, O_RDONLY );
	#endif 
	
	#if 1 // 임시코드...트롤텍 메인 화면...
	int fd = open( "trollMain.html", O_RDONLY );
	#endif

	if( fd == -1 )
	{
		perror( "File Open Error" );
	}

	// 파일전송...
	while( ( len = read( fd, transferMessage.contents, sizeof(transferMessage.contents) ) ) != 0 )
	{
			client->GetClientConnectSocket()->Write( &transferMessage, len+4 );
	}
	
	close( fd );	
	
	client->GetClientConnectSocket()->Close();
	*/
}

